/**
 * @项目名称 longlonggo-sample
 * @文件名称 ClassLoadTest.java  版本号：1.0
 * @创建日期 2018年9月27日 
 * @创建作者 me@longlonggo.com
 */
package classload;

/**
 * 说明：
 * 虚拟机规范则严格规定了，有且只有四种情况，必须立即对类进行初始化：
 * new、getStatic、putStatic或invokeStatic这4条字节码指令时，
 * 如果类没有进行过初始化，则需要先触发其初始化
 * 类初始化时机：
 *  1、创建类的实例对象时(new, 反射, 反序列化)
 *  2、使用类的类方法(静态方法)
 *  3、访问类的类变量(静态变量)
 *  4、赋值类的类变量(静态变量)
 * 注：final类型的类变量，如果在编译时就能确定 ，类变量相当于"宏变量",
 *    编译时直接替换成值，相当于常量。
 * @version 1.0
 * @author me@longlonggo.com
 *
 */
public class ClassLoadTest {
    static String classPath = "classload.Tester";

    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Class<?> c = cl.loadClass(classPath);
        c.newInstance();            //【1】java反射方式创建对象，会导致静态代码块初始化，输出：Tester类的静态初始化...
        
        //newInstance(): 弱类型,低效率,只能调用无参构造
        //new: 强类型,相对高效,能调用任何public构造
        //Class.forName("com.baidu.A")返回的是类
        //Class.forName("com.baidu.A").newInstance()返回的是object，表示对象已经初始化完毕了
        Class.forName(classPath);   //【2】由于上面【1】中类已被初始化，在此处不再打印静态代码块内容
        
        int value = Tester.value;
        Tester.name = "init";
        
        Tester.method();        
        
        Tester t = new Tester();
    }
}
